package com.kc.gb.device;

import com.kc.gb.device.common.properties.DeviceConfiguration;
import com.kc.gb.device.common.utils.SpringHelper;
import com.kc.gb.device.events.support.EmergencyEvent;
import javafx.animation.*;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcType;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Duration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ConfigurableApplicationContext;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 从 JDK 9 开始, jlink 可以用来从 JDK 中选择特定的模块来构建一个最小化的 JRE
 * 从 JDK 11 开始, JavaFX 被从 JDK 中剥离出来，需要开发者手动添加
 */
@Slf4j
public class JavaFxStarter extends javafx.application.Application {
    private static ConfigurableApplicationContext context;
    private static WebEngine webEngine;
    ExecutorService executor = Executors.newFixedThreadPool(2);
    private static String HOME = "http://localhost:8888/admin/device/index";

    @Override
    public void start(Stage primaryStage) throws Exception {
        System.setProperty("java.awt.headless", "false");
        System.setProperty("javafx.web.security", "false");
        System.setProperty("javafx.web.debug", "true");
        int width = 1280;
        int height = 720;

        primaryStage.getIcons().add(new Image(JavaFxStarter.class.getResourceAsStream("/static/public/images/icon.png")));
        primaryStage.setTitle("Quicktron 快仓");
        // 打开加载页, 防止启动时间过长, 以为是程序假死
        Scene loadingScene = createLoadingPane(width,height);
        primaryStage.setScene(loadingScene);
        primaryStage.show();

        // 非UI线程异步启动Spring
        executor.submit(()->{
            try {
                startSpring();
                // UI 现成更新 WebView
                Platform.runLater(() -> {
                    try {
                        Scene webScene = createWebScene(width,height);
                        primaryStage.setScene(webScene);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                });
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });
    }

    public static Scene createWebScene(int width,int height) throws IOException {
        // JavaFx UI 界面配置
        WebView webView = new WebView();
        JavaFxStarter.webEngine = webView.getEngine();
        webView.setContextMenuEnabled(true);
        webView.getEngine().setJavaScriptEnabled(true);
        log.info("UserAgent:{}", webView.getEngine().getUserAgent());
        log.info("Location:{}", webView.getEngine().getLocation());
        webView.getEngine().load(HOME);
        StackPane browser = new StackPane();
        browser.getChildren().add(webView);
        Scene scene = new Scene(browser, width, height);

        // 绑定全局快捷键 Ctrl+Shift+F9 => 全场急停事件
        KeyCombination keyComb = new KeyCodeCombination(KeyCode.F9,KeyCombination.CONTROL_DOWN,KeyCombination.SHIFT_DOWN);
        scene.addEventFilter(javafx.scene.input.KeyEvent.KEY_PRESSED, event -> {
            if (keyComb.match(event)) {
                SpringHelper.getApplicationContext().publishEvent(new EmergencyEvent(true));
            }
        });
        return scene;
    }

    public static Scene createLoadingPane(int width,int height) {
        VBox container = new VBox(15);
        container.setAlignment(javafx.geometry.Pos.CENTER);

        Label label = new Label("start...");
        label.setFont(Font.font("Arial", 16));

        // 波浪容器
        HBox waveContainer = new HBox(8);
        waveContainer.setAlignment(javafx.geometry.Pos.CENTER);

        // 创建5个波浪柱
        for (int i = 0; i < 5; i++) {
            Rectangle bar = new Rectangle(12, 40);
            bar.setFill(Color.valueOf("#ed6d00"));
            bar.setArcWidth(6);
            bar.setArcHeight(6);

            // 动画 - 使用不同的延迟创建波浪效果
            Timeline animation = new Timeline(
                    new KeyFrame(Duration.ZERO, new KeyValue(bar.heightProperty(), 40)),
                    new KeyFrame(Duration.seconds(0.5), new KeyValue(bar.heightProperty(), 60)),
                    new KeyFrame(Duration.seconds(1), new KeyValue(bar.heightProperty(), 40))
            );
            animation.setCycleCount(Timeline.INDEFINITE);
            animation.setDelay(Duration.millis(i * 100));
            animation.play();

            waveContainer.getChildren().add(bar);
        }

        container.getChildren().addAll(/*label,*/waveContainer);
        return new Scene(container, width, height);
    }

    private static void startSpring() throws Exception {
        // 启动Spring Boot应用上下文
        DeviceConfiguration.getDeviceProperties();
        context = new SpringApplicationBuilder(DeviceSpringApplication.class).run();
    }

    @Override
    public void stop() {
        log.info("JavaFxStarter stop...");
        // 关闭Spring Boot应用上下文，释放资源等清理工作
        if (this.context != null) {
            log.info("SpringContext stop...");
            this.context.close();
        }
        System.exit(1);
    }

    public static void main(String[] args) {
        launch(args); // 启动JavaFX应用
    }

    /**
     * 强制刷新，页面整体刷新可能会有闪屏问题
     */
    public static void reload() {
        if (webEngine != null) {
            Platform.runLater(() -> {
                String script = "window.location.reload();";
                webEngine.executeScript(script);
            });
        }
    }

    public static void executeScript(String script){
        if (webEngine != null) {
            Platform.runLater(() -> {
                webEngine.executeScript(script);
            });
        }
    }

    /**
     * 调用界面的数据刷新接口, 防止reload造成的闪屏
     */
    public static void refreshData(){
        if (webEngine != null) {
            Platform.runLater(() -> {
                String script = String.valueOf("refreshData();");
                webEngine.executeScript(script);
            });
        }
    }
}
